using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace nToolbox.WinForms
{
	/// <summary>
	/// This base class provides a Form that can ensure that it has been Loaded.
	/// </summary>
	/// <remarks>
	/// A typical use of this class is to ensure that a form is loaded and visible (and thus has a Window Handle)
	/// before using it as a progress indicator for non-UI threads.
	/// </remarks>
	public class LoadedForm : Form
	{
		#region WinForms Support
		#region Controls
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private Container components = null;

		#endregion
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.Size = new System.Drawing.Size(300,300);
			this.Text = "LoadedForm";
		}
		#endregion
		#endregion

		private readonly ManualResetEvent loadedEvent;

		/// <summary>
		/// Waits until <see>loadedEvent</see> has been signalled,
		/// ensuring that the form has been loaded.
		/// </summary>
		protected void EnsureLoaded()
		{
			loadedEvent.WaitOne();
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			loadedEvent.Set();
		}

		public LoadedForm()
		{
			loadedEvent = new ManualResetEvent(false);
			InitializeComponent();
		}
	}
}
